'use server';

import { auth, getSession } from '@/lib/auth';
import { db } from '@/lib/db';
import { user } from '@/lib/db/schema/auth';
import { shop } from '@/lib/db/schema/common';
import { extractWords, gorse } from '@/lib/gorse';
import { result, withZod } from '@/lib/utils';
import { APIError } from 'better-auth/api';
import { and, eq, inArray } from 'drizzle-orm';
import { revalidatePath } from 'next/cache';
import { z } from 'zod';
import { BizError, ErrorCode } from '../error';
import { shopFormSchema, shopInfoSchema } from './schema/shop';

export const signUpShop = withZod(shopFormSchema, async (data) => {
  try {
    if (!data.address) throw new BizError(ErrorCode.NotFound, '地址不存在');
    await auth.api.signUpEmail({
      body: {
        email: data.email,
        password: data.password,
        username: data.username,
        name: data.name,
      },
    });
    const shopUser = await db.query.user.findFirst({
      where: (user, { eq }) => eq(user.username, data.username),
    });
    if (!shopUser) throw new BizError(ErrorCode.NotFound, '用户不存在');
    await db
      .update(user)
      .set({
        role: 'shop',
      })
      .where(eq(user.id, shopUser.id));
    const res = await db
      .insert(shop)
      .values({
        userId: shopUser.id,
        name: data.shopName,
        address: data.address.address,
        longitude: data.address.longitude,
        latitude: data.address.latitude,
        contactPhone: data.contactPhone,
      })
      .returning({
        id: shop.id,
      });
    // gorse.insertItems([
    //   {
    //     id: res[0].id.toString(),
    //     labels: extractWords(data.shopName),
    //   },
    // ]);
    return result();
  } catch (error) {
    try {
      const shopUser = await db.query.user.findFirst({
        where: (user, { eq }) => eq(user.username, data.username),
      });
      if (shopUser) {
        await db.delete(shop).where(eq(shop.userId, shopUser.id));
        await db.delete(user).where(eq(user.id, shopUser.id));
      }
    } catch (error) {
      console.error(error);
    }
    console.error(error);
    if (error instanceof APIError)
      return result(error, error.message ?? '注册失败,请重试');
    return result(error, '注册失败,请重试');
  }
});

export const updateShopQualification = withZod(
  z.object({
    licenseKey: z.string().min(1, { message: 'key不能为空' }).nullable(),
    hygieneCertKey: z.string().min(1, { message: 'key不能为空' }).nullable(),
  }),
  async ({ licenseKey, hygieneCertKey }) => {
    try {
      const session = await getSession();
      if (!session?.user)
        throw new BizError(ErrorCode.Unauthorized, '用户未登录');
      await db
        .update(shop)
        .set({
          licenseKey,
          hygieneCertKey,
        })
        .where(eq(shop.userId, session.user.id));
      revalidatePath('/shop/info');
      return result();
    } catch (error) {
      return result(error, '更新失败,请重试');
    }
  },
);

export const shopUpdateShopStatus = withZod(
  z.enum(['reviewing']),
  async (status) => {
    try {
      const session = await getSession();
      if (session?.user.role !== 'shop')
        throw new BizError(ErrorCode.Unauthorized, '仅商家可操作');
      await db
        .update(shop)
        .set({
          status,
        })
        .where(
          and(
            eq(shop.userId, session.user.id),
            inArray(shop.status, ['unreviewed', 'rejected']),
          ),
        );
      revalidatePath('/shop/info');
      return result();
    } catch (error) {
      return result(error, '更新失败,请重试');
    }
  },
);

export const updateShopInfo = withZod(shopInfoSchema, async (data) => {
  try {
    const session = await getSession();
    if (!session?.user)
      throw new BizError(ErrorCode.Unauthorized, '用户未登录');
    const res = await db
      .update(shop)
      .set({
        ...data,
        address: data.address.address,
        longitude: data.address.longitude,
        latitude: data.address.latitude,
      })
      .where(eq(shop.userId, session.user.id))
      .returning({
        id: shop.id,
      });
    gorse.mergeItemLabels({
      id: res[0].id.toString(),
      labels: extractWords(
        data.name.concat(' ').concat(data.description ?? ''),
      ),
    });
    revalidatePath('/shop/info');
    return result();
  } catch (error) {
    return result(error, '更新失败,请重试');
  }
});

export const updateShopImageKeys = withZod(
  z.array(z.string()),
  async (imageKeys) => {
    try {
      const session = await getSession();
      if (!session?.user)
        throw new BizError(ErrorCode.Unauthorized, '用户未登录');
      await db
        .update(shop)
        .set({ imageKeys })
        .where(eq(shop.userId, session.user.id));
      revalidatePath('/shop/info');
      return result();
    } catch (error) {
      return result(error, '更新失败,请重试');
    }
  },
);

export const adminUpdateShopStatus = withZod(
  z.object({
    status: z.enum(['rejected', 'warning', 'closed', 'normal']),
    shopId: z.number(),
    rejectReason: z.string().optional(),
    warningReason: z.string().optional(),
  }),
  async ({ status, shopId, rejectReason, warningReason }) => {
    try {
      const session = await getSession();
      if (session?.user.role !== 'admin')
        throw new BizError(ErrorCode.Forbidden, '仅管理员可操作');
      const returnData = await db
        .update(shop)
        .set({
          status,
          rejectReason: status === 'rejected' ? rejectReason : undefined,
          warningReason: status === 'warning' ? warningReason : undefined,
        })
        .where(
          and(
            eq(shop.id, shopId),
            inArray(shop.status, ['reviewing', 'normal', 'warning', 'closed']),
          ),
        )
        .returning({
          name: shop.name,
          description: shop.description,
        });
      if (status === 'normal') {
        gorse.insertItems([
          {
            id: shopId.toString(),
            labels: extractWords(
              `${returnData[0].name} ${returnData[0].description}`,
            ),
          },
        ]);
      } else {
        gorse.rmItem(shopId.toString());
      }
      revalidatePath('/admin/shop');
      revalidatePath(`/admin/shop/${shopId}`);
      return result();
    } catch (error) {
      return result(error, '更新失败,请重试');
    }
  },
);
